using System;
using System.Drawing;
using System.Runtime.Serialization;

namespace Motorway_Simulator.Components
{
    /// <summary>
    /// Exit road unit component
    /// </summary>
    [Serializable()]
    public class Exit : RoadUnit, ISerializable
    {
        /// <summary>
        /// Unit icon to display bridge image on the road unit list view
        /// </summary>
        public readonly static Bitmap unitIcon = Motorway_Simulator.Properties.Resources.Exit;

        private Point endPoint;






        /// <summary>
        /// Constructor to initialize Exit road unit
        /// </summary>
        /// <param name="initX">X position of road unit</param>
        /// <param name="initY">Y position of road unit</param>
        /// <param name="direction">Direction of road unit</param>
        /// <param name="zoom">Initial Zoom level</param>
        public Exit(int initX, int initY, Direction direction, float zoom) : base()
        {
            // Default settings
            
            position.X = initX;
            position.Y = initY;
            this.direction = direction;
            RoadImage = Motorway_Simulator.Properties.Resources.Exit;
            ImageZoom = zoom;
            RoadImage = RotateImageClockWise(image);

            switch (direction)
            {
                case Direction.NORTH:
                    endPoint = new Point(position.X, position.Y);
                    break;

                case Direction.SOUTH:
                    endPoint = new Point(position.X, position.Y);
                    break;

                case Direction.EAST:
                    endPoint = new Point(position.X, position.Y);
                    break;
                case Direction.WEST:

                    endPoint = new Point(position.X, position.Y);
                    break;

            }
        }

        /// <summary>
        /// Drawing road unit icons
        /// </summary>
        /// <param name="g">Graphics</param>
        public override void Draw(Graphics g)
        {
            g.DrawImage(image, position.X, position.Y, ImageWidth, ImageHeight);
        }



        /// <summary>
        /// Gets or sets the end point.
        /// </summary>
        /// <value>The end point.</value>
        public Point EndPoint
        {
            get { return endPoint; }
            set { endPoint = value; }
        }

        /// <summary>
        /// Sets the controller.
        /// </summary>
        /// <value>The controller.</value>

        /// <summary>
        /// Gets the next point
        /// </summary>
        /// <param name="position"></param>
        /// <param name="speed"></param>
        /// <returns></returns>
        public override Point getNextPosition(Point position, int speed)
        {
            int newX = position.X;
            int newY = position.Y;
            if (direction == Direction.NORTH)
            {
                newX -= (int)(position.X/2f +speed);
                newY -= (int)(position.Y + speed);
                if (newX == endPoint.X)
                {
                    return endPoint;
                }
            }
            if (direction == Direction.SOUTH)
            {
                newX = (int)(position.X / 2f + speed);
                newY = (int)(position.Y + speed);
                if (newX == endPoint.X)
                {
                    return endPoint;
                }
            }
            if (direction == Direction.EAST)
            {
                newX = (int)(position.X / 2f + speed);
                newY = (int)(position.Y + speed);
                if (newX == endPoint.Y)
                {
                    return endPoint;
                }
            }
            if (direction == Direction.WEST)
            {
                newX = (int)(position.X / 2f + speed);
                newY = (int)(position.Y + speed);
                if (newX == endPoint.Y)
                {
                    return endPoint;
                }
            }
            return new Point(newX, newY);
            
        }

        #region ISerializable Members

        /// <summary>
        /// Add value for serialization
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Position", position);
            info.AddValue("Image", image);
            info.AddValue("ImageWidth", ImageWidth);
            info.AddValue("ImageHeight", ImageHeight);
            info.AddValue("RoadImage", roadImage);
            info.AddValue("ImageZoom", imageZoom);
            info.AddValue("Sign", sign);
            info.AddValue("HasSign", hasSign);
            info.AddValue("Direction", direction);
        }

        #endregion

        /// <summary>
        /// Is called to set values read from file
        /// </summary>
        /// <param name="info">Info</param>
        /// <param name="ctxt">ctxt</param>
        public Exit(SerializationInfo info, StreamingContext ctxt)
        {
            position = (Point)info.GetValue("Position", typeof(Point));
            image = (Bitmap)info.GetValue("Image", typeof(Bitmap));
            ImageWidth = (float)info.GetValue("ImageWidth", typeof(float));
            ImageHeight = (float)info.GetValue("ImageHeight", typeof(float));
            roadImage = (Bitmap)info.GetValue("RoadImage", typeof(Bitmap));
            imageZoom = (float)info.GetValue("ImageZoom", typeof(float));
            sign = (Sign)info.GetValue("Sign", typeof(Sign));
            hasSign = (bool)info.GetValue("HasSign", typeof(bool));
            direction = (Direction)info.GetValue("Direction", typeof(Direction));
            //Get the values from info and assign them to the appropriate properties
        }

        /// <summary>
        /// Determines whether [is not in current road unit] [the specified vehicle].
        /// </summary>
        /// <param name="vehicle">The vehicle.</param>
        /// <returns>
        /// 	<c>true</c> if [is not in current road unit] [the specified vehicle]; otherwise, <c>false</c>.
        /// </returns>
        public override bool IsNotInCurrentRoadUnit(Vehicle vehicle)
        {
            switch (this.Direction1)
            {
                case Direction.NORTH:
                    if (Position.Y  >= vehicle.CurrentPoint.Y)
                    {
                        return true;
                    }
                    break;

                case Direction.SOUTH:
                    if (Position.Y >= vehicle.CurrentPoint.Y)
                    {
                        return true;
                    }
                    break;
                case Direction.WEST:

                    if (Position.X + ImageWidth >= vehicle.CurrentPoint.X)
                    {
                        return true;
                    }
                    break;
                case Direction.EAST:
                    if (Position.X + ImageWidth <= vehicle.CurrentPoint.X)
                    {
                        return true;
                    }
                    break;

            }
            return false;

        }
    
    }
}